package com.asdf.db.operations.stat;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.asdf.db.operations.IDBOperation;
import com.asdf.db.results.ResultStatus;
import com.asdf.db.results.stat.StatResult;
import com.asdf.external.DBUsageDetails;

/** A base class for statistics search operations by date and id
 * @author so4i2014
 *
 */
public abstract class StatOp implements IDBOperation<StatResult>
{
	static long ONE_DAY = 1000L * 60L * 60L *24L;
	
	private List<DBUsageDetails> source = null;
	private List<DBUsageDetails> result = null;
	private long long_date = -1;
	private String id = null;
	
	/** A list we gonna search in.
	 * @param source
	 */
	public StatOp(List<DBUsageDetails> source) {
		super();
		this.source = source;
	}

	/** Function for comparing dates.
	 * @param date - date compare to.
	 * @return True <==> @date is the same date (year, month, day) as this
	 */
	private boolean isSameDate(Date date)
	{
		long long_date = date.getTime();
		
		// this.date should be set to midnight
		// this.date <= date of bill < this.date + 24 hours
		return long_date >= this.long_date && long_date < this.long_date + ONE_DAY;
	}
	
	/** Returns id of the user or of the airport (due to the operation).
	 * @param usage - the statistics usage to look id in.
	 * @return The id.
	 */
	abstract protected String getId(DBUsageDetails usage);
	
	public List<DBUsageDetails> getResult()
	{
		return this.result;
	}
	
	/** Sets the we are looking for.
	 * @param id
	 */
	public void setId(String id)
	{
		this.id = id;
	}

	/** Sets the date we are looking for.
	 * @param date
	 */
	public void setDate(Date date)
	{
		this.long_date = date.getTime();
		// Rounding the date to midnight
		this.long_date -= this.long_date % ONE_DAY;
	}

	/* (non-Javadoc)
	 * @see com.asdf.db.operations.IDBOperation#perform()
	 */
	public StatResult perform()
	{
		StatResult res = new StatResult();
		
		if (long_date < 0 || id == null)
		{
			res.setStatus(ResultStatus.BadArguments);
			return res;
		}
		
		this.result = new ArrayList<DBUsageDetails>();
		for (int i = 1; i < source.size() + 1; i++)
		{
			DBUsageDetails cur = source.get(i);
			String id = getId(cur);

			if (isSameDate(cur.getDate()) && id != null && id.equalsIgnoreCase(this.id))
				this.result.add(cur);
		}
		res.setStatus(ResultStatus.OK);
		return res;
	}
}
